package com.qfedu.department.service.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.transaction.Transactional;

import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.qfedu.common.entity.WoPage;
import com.qfedu.department.dto.LeaveDto;
import com.qfedu.department.po.Staff;
import com.qfedu.department.repository.StaffRepository;
import com.qfedu.department.service.LeaveService;
import com.qfedu.psys.dto.WoUser;

@Service
@Transactional
public class LeaveServiceImpl implements LeaveService {
	private final static Logger LOG = LogManager.getLogger(LeaveServiceImpl.class);

	@Resource
	private RuntimeService runtimeService;
	
	@Resource
	private TaskService taskService;
	
	@Resource
	private FormService formService;
	
	@Resource
	private StaffRepository staffRepository;
	
	@Resource
	private HistoryService historyService;
	
	@Override
	public void create(WoUser currentUser, LeaveDto dto) {
		// 启动流程
		ProcessInstance pi = runtimeService.startProcessInstanceByKey(PROC_DEF_KEY);
		// 根据流程示例id获取当前任务
		Task task = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();
		// 获取当前人员
		Staff apply = staffRepository.findByUserId (currentUser.getId());
		// 设置任务执行人id
		task.setAssignee(apply.getId());
		// 组装“申请”任务的表单数据并提交
		Map<String, String> form = new HashMap<String, String>();
		form.put("applyId", apply.getId());
		form.put("applyName", apply.getName());
		form.put("applyHours", dto.getApplyHours().toString());
		form.put("applyType", dto.getApplyType());
		form.put("applyReason", dto.getApplyReason());
		formService.submitTaskFormData(task.getId(), form);
	}

	private Object getVariableValue (String key, String processInstanceId) {
		HistoricVariableInstance hvi = historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).variableName(key).singleResult();
		if (hvi != null) {
			return hvi.getValue();
		}
		return null;
	}
	
	@Override
	public WoPage<LeaveDto> getPageData(WoUser currentUser, String searchContent, Long page, Long size) {
		//
		Staff currentStaff = staffRepository.findByUserId (currentUser.getId());
		HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().processDefinitionKey(PROC_DEF_KEY);
		Long count = query.count();
		List<HistoricProcessInstance> list = query.orderByProcessInstanceStartTime().desc().listPage((int) ((page - 1) * size), size.intValue());
		List<LeaveDto> dtos = new ArrayList<LeaveDto>();
		for (HistoricProcessInstance hpi : list) {
			LeaveDto dto = new LeaveDto ();
			dto.setApplyHours((Long)this.getVariableValue("applyHours", hpi.getId()));
			dto.setApplyId((String)this.getVariableValue("applyId", hpi.getId()));
			dto.setApplyName((String)this.getVariableValue("applyName", hpi.getId()));
			dto.setApplyType((String)this.getVariableValue("applyType", hpi.getId()));
			dto.setApplyReason((String)this.getVariableValue("applyReason", hpi.getId()));
			dto.setCurrentUserId(currentStaff.getId());
			dto.setEndTime(hpi.getEndTime());
			if (dto.getEndTime() == null) {
				Task task = taskService.createTaskQuery().processInstanceId(hpi.getId()).active().singleResult();
				List<IdentityLink> users = taskService.getIdentityLinksForTask(task.getId());
				dto.setTask(task, users, currentUser.getStaffId());
			}
			dto.setProcessInstanceId(hpi.getSuperProcessInstanceId());
			dto.setStartTime(hpi.getStartTime());
			dtos.add(dto);
		}
		return new WoPage<LeaveDto>(dtos, count);
	}
}
